/*
* file: common.hpp
* description: 提出行为树使用过程中通用的方法
* author: liufeng
* date: 20230427
*/

#pragma once
#include <string>
#include <iostream>
#include "behaviac_types.h"
#include "FileExist.hpp"

/*
  name:InitBehaviac
  desc:初始化behaviac 环境
  param：
    filePath: 行为树路径
    fileFormat：行为树格式（有 xml,bson,cpp)

  return:
    成功标识
    
*/
inline bool InitBehaviac(const std::string& filePath, behaviac::Workspace::EFileFormat fileFormat = behaviac::Workspace::EFF_xml)
{
    std::cout << __FUNCTION__ << std::endl;

    behaviac::Workspace::GetInstance()->SetFilePath(filePath.c_str());
    behaviac::Workspace::GetInstance()->SetFileFormat(fileFormat);
    return true;
}

/*
  name:InitAgent
  desc:初始化Agent，实例化行为树跟节点
  param：
    btfileName: 行为树文件名
  return:
    根节点指针
    
*/
template <typename T>
inline T* InitAgent(const std::string& btfileName)
{
    std::cout << __FUNCTION__ << std::endl;
    T* agent = behaviac::Agent::Create<T>();
    if(agent)
    {
        bool bRet =  agent->btload(btfileName.c_str());
        agent->btsetcurrent(btfileName.c_str());
        std::string path = behaviac::Workspace::GetInstance()->GetFilePath();
        path += btfileName;
        if(!bRet){
          std::cout <<"\t load "<< path << " fail!"<< std::endl;
          abort();
        }
        else
        {
          std::cout <<"\t load "<< path << " success!"<< std::endl;
        }
    }

    return agent;
}

/*
  name:UpdateAgent
  desc: 更新智能体
  param：
    agent: 智能体节点

  return:
    状态
    
*/
template <typename T>
inline behaviac::EBTStatus UpdateAgent(T* agent)
{
    static int frame = 0;

    frame++;
    std::cout << __FUNCTION__ << ":frame = " << frame << std::endl;
    behaviac::EBTStatus status  = behaviac::EBTStatus::BT_INVALID;
    if(agent)
    {
      status = agent->btexec();
      std::cout <<"\t btexec success!"<< std::endl;
    }
    return status;
}

/*
  name:CleanupAgent
  desc: 销毁智能体
  param：
    agent: 智能体节点

  return:
    
*/
template <typename T>
inline void CleanupAgent(T* agent)
{
    std::cout << __FUNCTION__ << std::endl;

    if(agent)
    {
        behaviac::Agent::Destroy(agent);
    }
}

/*
  name:CleanupBehaviac
  desc: 销毁behaviac环境
  param：
  return:
*/
inline void CleanupBehaviac()
{
    std::cout << __FUNCTION__ << std::endl;
    behaviac::Workspace::GetInstance()->Cleanup();
}